package com.cs307.redcross.client;

import java.io.Serializable;
import java.security.MessageDigest;
import java.util.Date;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.SimplePanel;

public class LoginContent extends Content implements Serializable {

	private static final long serialVersionUID = 689764351669829075L;
	private PasswordTextBox textBoxPassword;
	private TextBox textBoxUsername; 
	private CheckBox chckbxRememberThisComputer;
	private Boolean isLogin = false;
	private final DatabaseHandlerServiceAsync databaseHandlerService = GWT.create(DatabaseHandlerService.class); 
	private int sessionID = 0;
	
	RegisterUserContent reg;
	forgotPassPopupPanel forgot;
	

	@SuppressWarnings("deprecation")
	public LoginContent() {
		FlexTable flexTable = new FlexTable();
		initWidget(flexTable);
		flexTable.setSize("242px", "200px");
		
		Label lblUsername = new Label("Email");
		flexTable.setWidget(0, 0, lblUsername);
		lblUsername.setHeight("");
		
		textBoxUsername = new TextBox();
		flexTable.setWidget(1, 0, textBoxUsername);
		
		Label lblNewLabel = new Label("Password");
		flexTable.setWidget(2, 0, lblNewLabel);
		
		textBoxPassword = new PasswordTextBox();
		textBoxPassword.addKeyUpHandler(new KeyUpHandler() {
			public void onKeyUp(KeyUpEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					logInCheck();
				}
			}
		});
		flexTable.setWidget(3, 0, textBoxPassword);
		
		chckbxRememberThisComputer = new CheckBox("Remember this computer ");
		flexTable.setWidget(4, 0, chckbxRememberThisComputer);

		
		VerticalPanel verticalPanel = new VerticalPanel();
		flexTable.setWidget(5, 0, verticalPanel);

		Button btnLogIn = new Button("Log in");
		btnLogIn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				logInCheck();
			}
		});
		
		verticalPanel.add(btnLogIn);
		
		
		Hyperlink hprlnkSignUp = new Hyperlink("Sign up", false, "");
		hprlnkSignUp.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				reg = new RegisterUserContent();
				reg.setPopupPosition(150, 75);
				reg.setGlassEnabled(true);
				reg.setModal(true);
				reg.show();
			}
		});
		
		SimplePanel simplePanel = new SimplePanel();
		flexTable.setWidget(6, 0, simplePanel);
		simplePanel.setHeight("31px");
		flexTable.setWidget(7, 0, hprlnkSignUp);
		
		Hyperlink hprlnkForgotPassword = new Hyperlink("Forgot Password", false, "");
		hprlnkForgotPassword.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				forgot = new forgotPassPopupPanel();
				forgot.setPopupPosition(150, 75);
				forgot.setGlassEnabled(true);
				forgot.setModal(true);
				forgot.show();
			}
		});
		flexTable.setWidget(8, 0, hprlnkForgotPassword);
		
	}
	//checks to see if the person is log in 
	private void logInCheck()
	{
		if (textBoxPassword.getText().length() == 0 || textBoxUsername.getText().length() == 0) 
		{
			Window.alert("Username or password is empty.");	
		}
		else 
		{
			// gets the usernames and paswords from the login screen  
			String enteredUsername = textBoxUsername.getText();
			//String enteredPassword = textBoxPassword.getText();
			String enteredPassword = Person.encrypt(textBoxPassword.getText());
			// calls the server to check for valid username password
			databaseHandlerService.validPassword(enteredUsername, enteredPassword, new AsyncCallback<Integer>() {
				public void onFailure(Throwable caught) {
					Window.alert("Cannot connect to the server");
				}
				public void onSuccess(Integer result) {
						if(result > -1)
						{
							isAdmin(result);
							
							isLogin = true;
							sessionID = result;
							
							if(chckbxRememberThisComputer.getValue())
							{
								 final long DURATION = 1000 * 60 * 60 * 24 * 14; //duration remembering login. 2 weeks in this example.
								 Date expires = new Date(System.currentTimeMillis() + DURATION);
								 Cookies.setCookie("sid", result.toString(), expires, null, "/", false);
							}
							
							
							
						}
						else 
						{
							Window.alert("You have entered an incorrect username or password.");
							isLogin = false;
						}
				}
			});	
		}
	}
	private void isAdmin(int sessionID)
	{
	 
		databaseHandlerService.getUserFromSessionId(sessionID, new AsyncCallback<Person>(){

				@Override
				public void onFailure(Throwable caught) {
					Window.alert("Cannot connect the server");
				}

				@Override
				public void onSuccess(Person result) {
					if (result == null) {
						Window.alert("Cannot connect to the server.");
						return;
					}
					Server.currentUser = result;
					ImageHeader.hprlnkLogOut.setVisible(true);
					
					if (result.username.equals("dev")) {
						RootPanel header = RootPanel.get("header");
						header.add(new DeveloperHeader());
						header.setVisible(true);
						ContentPanel.getInstance().setContent(new HomeContent());
						return;
					}
					
					
					if (result instanceof Administrator)
					{
						RootPanel header = RootPanel.get("header");
						header.add(new AdminHeader());	
						header.setVisible(true);
						ContentPanel.getInstance().setContent(new HomeContent());
						
					}
					else 
					{
						
						RootPanel header = RootPanel.get("header");
						header.add(new VolunteerHeader());
						header.setVisible(true);
						ContentPanel.getInstance().setContent(new HomeContent());
					}
				}
			
		});
		
	}
	
	//allows other classes to see if the user is logged in
	public Boolean checkLogin()
	{
		return  isLogin; 
	}
	
	public int getSessionID()
	{
		return sessionID;
	}
	
	//based on code from http://www.java2s.com/Tutorial/Java/0490__Security/Createanencryptedstringforpassword.htm
	private String encrypt(String password )
	{
		 String algorithm = "SHA";

	        byte[] plainText = password.getBytes();

	        MessageDigest md = null;

	        try {		
	            md = MessageDigest.getInstance(algorithm);
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
			
	        md.reset();		
	        md.update(plainText);
	        byte[] encodedPassword = md.digest();

	        StringBuilder sb = new StringBuilder();
	        for (int i = 0; i < encodedPassword.length; i++) {
	            if ((encodedPassword[i] & 0xff) < 0x10) {
	                sb.append("0");
	            }

	            sb.append(Long.toString(encodedPassword[i] & 0xff, 16));
	        }
		return sb.toString();
	}
	
	
	
}
